#!/usr/bin/env python
# encoding: utf-8
# @author: Lin Han
# @contact: voldemort22@126.com
# @file: deprecated_app.py
# @time: 2021/4/7 18:14
# @desc:
import json

from fastapi import APIRouter, Request, BackgroundTasks

from application.history_clamp.crud import get_history_clamp_in_assigned_scene, get_standard_clamp_by_history_clamp
from application.scene.crud import retrieve_history_clamp_from_scene, retrieve_standard_clamp_from_scene, retrieve_standard_clamp_oss_address_from_scene, retrieve_history_clamp_oss_address_from_scene, \
    retrieve_standard_clamp_by_history_clamp, retrieve_history_clamp_from_scene_v2, retrieve_standard_clamp_from_scene_v2
from background.background_update import update_06
from cache.redis_pool import get_redis
from models.queryModels import CreateScene, MultipleConditionQueryTrainingData, UpdateScene
from utils.mongo_tools import delete_mongo_value, retrieve_one_mongo_value, retrieve_mongo_values, \
    retrieve_all_mongo_values, update_mongo_value, create_one_mongo_value
from views.configs import *
from views.crud import create_scene, keyword_search_scene, separate_page

scene_router = APIRouter(
    prefix="/api/scene",
    tags=["scene"],
)


@scene_router.get("/v1/model_oss_address")
def download_one_scene_model(sceneNumber: str):
    """
    返回该场景下的所有模型指定格式的OSS链接地址。

    - :param queryModel:
    - :return:
    """
    model = {
        "data":
            {
                "result": {
                    "historyClampOssAddress": [],
                    "standardClampOssAddress": [],
                },
                "historyClampQuantity": 0,
                "standardClampQuantity": 0,
            }
    }
    scene = retrieve_one_mongo_value(sceneNumber, collection_name=SCENE_COLLECTION)[0]
    historyClampOssAddress = []
    for i in scene["historyClamp"]:
        try:
            temp_history_clamp = retrieve_all_mongo_values(
                {"number": i},
                collection_name=HISTORY_CLAMP_COLLECTION,
            )[0]["file"][STP_OSS_ADDRESS]
            if temp_history_clamp is not None:
                historyClampOssAddress.append(temp_history_clamp)
        except:
            continue

    standardClampOssAddress = []
    for i in scene["standardClamp"]:
        try:
            temp_standard_clamp = retrieve_all_mongo_values(
                {"number": i},
                collection_name=STANDARD_CLAMP_COLLECTION,
            )[0]["file"][STL_OSS_ADDRESS]
            if temp_standard_clamp is not None:
                standardClampOssAddress.append(temp_standard_clamp)
        except:
            continue

    model["data"]["historyClampQuantity"] += len(historyClampOssAddress)
    model["data"]["standardClampQuantity"] += len(standardClampOssAddress)

    model["data"]["result"]["historyClampOssAddress"].extend(historyClampOssAddress)
    model["data"]["result"]["standardClampOssAddress"].extend(standardClampOssAddress)
    model["status"] = 1
    return model


@scene_router.get("/v1/all_model_oss_address")
def download_all_scene_model():
    """
    返回所有场景下的所有模型指定格式的OSS链接地址。

    - :param queryModel:
    - :return:
    """
    # 先取出所有的场景数据，去mongo里面取
    scenes = retrieve_all_mongo_values(
        filter_conditions={},
        collection_name=SCENE_COLLECTION,
    )
    data = {}

    for i in scenes:
        scene = retrieve_one_mongo_value(i["number"], collection_name=SCENE_COLLECTION)[0]
        temp_scene = {
            "history_clamp": retrieve_history_clamp_oss_address_from_scene(scene),
            "standard_clamp": retrieve_standard_clamp_oss_address_from_scene(scene),
        }
        data[i["number"]] = temp_scene
    model = {"data": data, "status": 1}
    return model


@scene_router.post("/v3/scenes")
def multiple_condition_query_v3(queryModel: MultipleConditionQueryTrainingData, background_tasks: BackgroundTasks):
    """
    列表查询多条训练数据（场景）。输入参数所有字段均可为空。

    - :param queryModel:
    - :return:
    """
    redis_connection = get_redis(port=SCENE_REDIS_PORT)
    model = {"data": {"result": [], "historyClampQuantity": 0, "standardClampQuantity": 0, }}

    # 先把redis中的符合的scene key都拿出来
    try:
        scene_number_list = redis_connection.get("scene")
        scene_number_list = json.loads(scene_number_list)
        # 用上面的number列表去redis中查询所有scene
        result = redis_connection.mget(*scene_number_list)
        result = [json.loads(i) for i in result if i is not None]
    except:
        result = retrieve_all_mongo_values({}, collection_name=SCENE_COLLECTION)
        background_tasks.add_task(update_06)

    result = sorted(result, key=lambda x: x["name"])
    result = keyword_search_scene(queryModel, result)
    model["data"]["total"] = len(result)
    if len(result) > 0:

        history_clamp = []
        standard_clamp = []
        for i in result:
            if "historyClamp" in i.keys() and i["historyClamp"] is not None:
                history_clamp.extend(i["historyClamp"])

            if "standardClamp" in i.keys() and i["standardClamp"] is not None:
                standard_clamp.extend(i["standardClamp"])

        model["data"]["standardClampQuantity"] = len(set(standard_clamp))
        model["data"]["historyClampQuantity"] = len(set(history_clamp))
        model["data"]["result"] = separate_page(result, page=queryModel.page, pagesize=queryModel.pagesize)
    model["status"] = 1
    return model


@scene_router.post("/v2/scene")
def create_v2(queryModel: CreateScene, background_tasks: BackgroundTasks):
    """
    ## 新增一条训练场景的完整信息，TODO

    - :param queryModel: 创建数据用的类，其中historyClamp和standardClamp可以为空，场景名称、描述和焊点是必填的。
    - :return: 创建好的完整信息也返回给前端。
    """
    redis_connection = get_redis(port=SCENE_REDIS_PORT)
    model = {"data": {}, "status": 0}
    # 首先判断传过来的queryModel是否满足条件
    scene_name = redis_connection.get("scene_name")
    scene_desc = redis_connection.get("scene_desc")
    scene_name = json.loads(scene_name)
    scene_desc = json.loads(scene_desc)
    if queryModel.name in scene_name:
        model["message"] = "场景名字已经存在，请勿重复创建。"
        return model
    if queryModel.desc in scene_desc:
        model["message"] = "场景描述已经存在，请勿重复创建。"
        return model

    data = create_scene(
        name=queryModel.name,
        desc=queryModel.desc,
        rpsNumber=queryModel.rpsNumber,
    )
    create_one_mongo_value(
        data,
        collection_name=SCENE_COLLECTION,
    )
    background_tasks.add_task(update_06)
    model["data"] = data
    model["status"] = 1
    return model


@scene_router.delete("/v2/scene")
def delete_v2(number: str, background_tasks: BackgroundTasks):
    """
    根据训练场景的编号删除训练场景（一次删除单条数据）

    - :param number:
    - :return:
    """
    model = {"data": False}
    try:
        delete_mongo_value(
            number=number,
            collection_name=SCENE_COLLECTION
        )
        background_tasks.add_task(update_06)
        model["data"] = True
        model["status"] = 1
    except:
        model["status"] = 0
    return model


@scene_router.get("/v3/scene")
def retrieve_v3(number: str):
    """
    ## 查询场景，根据传入的number

    :param request:
    :param number:
    """
    redis_connection = get_redis(port=SCENE_REDIS_PORT)
    model = {
        "data": {
            "result": {
                "historyClamp": [],
                "standardClamp": [],
            },
            "historyClampQuantity": 0,
            "standardClampQuantity": 0,
        },
    }
    scene = redis_connection.get(number)
    scene = json.loads(scene)

    history_clamp = redis_connection.mget(*scene["historyClamp"])
    history_clamp = [json.loads(i) for i in history_clamp if i is not None]
    model["data"]["result"]["historyClamp"] = history_clamp
    # 这个判断不能少，因为historyClamp列表里有的夹具编号不一定在数据库里有
    if len(model["data"]["result"]["historyClamp"]) > 0:
        model["data"]["historyClampQuantity"] = len(model["data"]["result"]["historyClamp"])

    if len(scene["standardClamp"]) > 0:
        standard_clamp = redis_connection.mget(*scene["standardClamp"])
        standard_clamp = [json.loads(i) for i in standard_clamp if i is not None]
        model["data"]["result"]["standardClamp"] = standard_clamp
        # 这个判断不能少，因为standardClamp列表里有的夹具编号不一定在数据库里有
        if len(model["data"]["result"]["standardClamp"]) > 0:
            model["data"]["standardClampQuantity"] = len(model["data"]["result"]["standardClamp"])

    model["status"] = 1
    return model


@scene_router.put("/v1/scene")
def update(queryModel: UpdateScene, background_tasks: BackgroundTasks):
    """
    修改训练数据（场景）的属性

    - :param queryModel: 要更新的场景信息，其中number是必填的
    - :return:
    """
    scene = retrieve_all_mongo_values(
        {"number": queryModel.number},
        collection_name=SCENE_COLLECTION,
    )[0]
    if queryModel.name is not None:
        scene['name'] = queryModel.name
    if queryModel.desc is not None:
        scene['desc'] = queryModel.desc
    if queryModel.rpsNumber is not None:
        scene['rpsNumber'] = queryModel.rpsNumber
    if queryModel.historyClamp is None or len(queryModel.historyClamp) > 0:
        scene['historyClamp'] = queryModel.historyClamp
    if queryModel.standardClamp is None or len(queryModel.standardClamp) > 0:
        scene['standardClamp'] = queryModel.standardClamp

    background_tasks.add_task(update_06)
    updateInfo = {"$set": scene}
    update_mongo_value(
        {"number": queryModel.number},
        updateInfo,
        collection_name=SCENE_COLLECTION,
    )
    model = {"data": True, "status": 1}
    return model


@scene_router.get("/v3/scene_by_name")
def retrieve_by_scene_name_v3(name: str, background_tasks: BackgroundTasks):
    """
    返回一条训练场景的完整信息

    - :param number: 编号
    - :return:
    """
    scene_redis_connection = get_redis(port=SCENE_REDIS_PORT)
    # history_clamp_redis_connection = get_redis(port=HISTORY_CLAMP_REDIS_PORT)
    try:
        scene = scene_redis_connection.get(name)
        scene = json.loads(scene)
    except:
        scenes = retrieve_all_mongo_values({}, collection_name=SCENE_COLLECTION)
        scene = [i for i in scenes if i["name"] == name][0]
        background_tasks.add_task(update_06)
    model = {"data": scene, "status": 1}
    return model


@scene_router.get("/v3/data_board")
def data_board():
    """
    ## 为数据看板提供数据

    :param request:
    :param number:
    """
    redis_connection = get_redis(port=SCENE_REDIS_PORT)
    model = {"data": {"result": [], "historyClampQuantity": 0, "standardClampQuantity": 0, }}

    # 先把redis中的符合的scene key都拿出来
    scene_number_list = redis_connection.get("scene")
    scene_number_list = json.loads(scene_number_list)
    # 用上面的number列表去redis中查询所有scene
    result = redis_connection.mget(*scene_number_list)
    result = [json.loads(i) for i in result]

    result = sorted(result, key=lambda x: int(x["name"]))
    model["data"]["total"] = len(result)
    if len(result) > 0:

        for i in result:
            if "history" in i.keys():
                history_clamp_quantity = len(i["historyClamp"])
                model["data"]["historyClampQuantity"] += history_clamp_quantity

            if "standard" in i.keys():
                standard_clamp_quantity = len(i["standardClamp"])
                model["data"]["standardClampQuantity"] += standard_clamp_quantity

        model["data"]["result"] = result
    model["status"] = 1
    return model
